#pragma once

#include "noncopyable.h"
#include "Timestamp.h"

#include <vector>
#include <unordered_map>

class EventLoop;
class Channel;

/**
 * nuduo库中多路事件分发器的核心 IO复用模块
 * 将Poller作为父类，EPollPoller、PollPoller继承Poller，实现poll和epoll的兼容
 */
class Poller : noncopyable
{
public:
    using ChannelList = std::vector<Channel *>;

    Poller(EventLoop *loop);
    // 虚析构函数，继承后自动构成重写，
    // 在释放 指向子类对象 的 基类指针 时（重写+父类指针/引用=多态）可以调用子类的析构函数进行资源释放，避免内存泄漏
    virtual ~Poller() = default;

    // 给不同的I/O复用保留统一的接口，让其重写
    virtual Timestamp poll(int timeoutMs, ChannelList *activeChannels) = 0; // epoll_wait
    virtual void updateChannel(Channel *channel) = 0;                       // epoll_ctl---EPOLL_CTL_ADD/MOD
    virtual void removeChannel(Channel *channel) = 0;                       // epoll_ctl---EPOLL_CTL_DEL

    // 判断channel是否在当前poller中
    bool hasChannel(Channel *channel) const;

    //供EventLoop调用，获取所采用的 多路复用模式，epoll或poll
    static Poller* newDefaultPoller(EventLoop* loop);

    //为了调试
    EventLoop *ownerLoop() { return ownerLoop_; }
protected:
    //建立sockfd和其所述Channel的映射关系
    using ChannelMap = std::unordered_map<int, Channel *>;
    ChannelMap channels_;

private:
    EventLoop *ownerLoop_;
};